systemverilog

您所在的位置:网站首页 systemverilog new子类 systemverilog

systemverilog

2024-07-13 12:41| 来源: 网络整理| 查看: 265

文章目录 1.句柄与对象2.静态转换和动态转换2.1 静态转换2.2 动态转换 在看绿皮书时,对 $cast 理解的很浅显,在查阅了更多相关内容,甚至发现理解还有误,所以下面对它进行详细的总结。

1.句柄与对象 1.句柄:指向对象的指针 2.对象:对象是类的一个实例 BadTr bad;//创建类的句柄 bad = new();//创建对象 2.静态转换和动态转换

SV类型转换分为两种方法,一种是静态类型转换,另一种是动态类型转换。

2.1 静态转换

静态转换即需要在转换的表达式前加上单引号即可,该方式不会对转换值做检查。如果发生转换失败,我们也无从得知。但是 $cast 的 task 却不是这样,它在运行时将进行类型检查,如果转换失败,会产生运行时错误。

int a = 2; real b; b = real'(a); 2.2 动态转换

动态转换即需要使用系统函数 $cast(tgt,src) 做转换,为加深理解可以将 , 等价于 =,即 tgt = src 将 src 类型转换成 tgr 类型。 在这里插入图片描述 父类站的高,子类在底下,从父类向子类的转换,称为向下类型转换; 子类向父类的转换称为向上类型转换。 由于子类继承了父类,拥有了父类的一切属性,除此之外,子类还有自己独特的个性,这是父类没有的。

向上类型转换:合法类型转换,父类句柄指向子类对象,句柄仍然能对子类对象与父类相同的属性进行访问。向下类型转换:非法类型转换,因为子类含有比父类更丰富的属性,有可能访问父类并不包含的资源,导致越界。 向上类型转换: base_class bc; sub_class sc = new(); bc = sc;//父类句柄指向子类对象这是正确的 class Transaction; rand bit [31:0] src; virtual function void display(input string prefix=""); $display(); endfunction endclass class BadTr extends Transaction; bit crc; virtual function void display() super.display(prefix); $display(); endfunction endclass Transaction tr; BadTr bad,bad2; bad = new();//构建BadTr扩展对象 tr = bad;//基类句柄指向扩展对象 $display(tr.src);//显示基类对象的变量成员 tr.display;//调用BadTr::display 如果display未用virtual修饰 tr.display;//调用Transaction::display

调用display函数时,调用的是父类还是派生类的diaplay函数 调用时,首先通过句柄类型找到该函数,查看有无virtual修饰符

有virtual修饰符,那么就调用实际对象类型的display函数;无virtual修饰符,那么就调用句柄类型的display函数; 注意: tr.crc错误,由于tr句柄是Transaction类型的,所以看不到crc变量 将一个父类句柄赋值给一个子类句柄并不总是非法的。 满足以下条件是合法的:父类句柄指向一个子类对象源对象和目的句柄是同一类或者是目的句柄类型的子类,转换合法

使用 $cast(tgt,src) 来实现句柄类型的动态转换。

而且 $cast(tgt,src) 会检查句柄所指的对象类型,而不仅仅检查句柄本身。

一旦源对象跟目的句柄是同一类型,或者是目的句柄的扩展类, $cast() 函数执行即会成功,返回1,否则返回0

向下类型转换 base_class bc; sub_class sc1,sc2; sc2 = new(); bc = sc2;//父类句柄指向子类对象 $cast(sc1,bc);//通过cast方式可以实现,可以看到bc的句柄类型虽然是父类,但其指的对象类型是子类

这样的类型转换好处: 要处理具体的内容就需要将父类句柄类型转换成子类类型才能访问子类特有的资源。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3